package com.whz.governance.http.client;

import com.alibaba.cloud.sentinel.custom.SentinelProtectInterceptor;
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.UrlCleaner;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.whz.generic.api.ApiResponseWrapper;
import com.whz.generic.json.JacksonUtils;
import com.whz.generic.message.GenericMessageAccessor;
import com.whz.generic.spring.SpringUtils;
import lombok.experimental.UtilityClass;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpResponse;

import java.util.Optional;

/**
 * sentinel 的feign通用降级处理器
 *
 * @author whz
 * @see SentinelProtectInterceptor
 */
@UtilityClass
public final class StaticUrlCleaner {

    public static String clean(String originUrl) {
        Optional<UrlCleaner> op = SpringUtils.getBean(UrlCleaner.class);
        if (op.isPresent()) {
            return op.get().clean(originUrl);
        }
        return originUrl;
    }

    public static ClientHttpResponse staticFallBack(HttpRequest request, byte[] body,
                                                    ClientHttpRequestExecution execution, BlockException ex) {
        Optional<CommonFeignFallBackProvider> op = SpringUtils.getBean(
                CommonFeignFallBackProvider.class);
        if (op.isPresent()) {
            return op.get().fallBackHandler(request, body, execution, ex);
        }
        return new SentinelClientHttpResponse(getBlockString());
    }

    public static ClientHttpResponse staticBlock(HttpRequest request, byte[] body,
                                                 ClientHttpRequestExecution execution, BlockException ex) {
        Optional<CommonFeignFallBackProvider> op = SpringUtils.getBean(
                CommonFeignFallBackProvider.class);
        if (op.isPresent()) {
            return op.get().blockHandler(request, body, execution, ex);
        }
        return new SentinelClientHttpResponse(getBlockString()) {
            @Override
            public int getRawStatusCode() {
                return HttpStatus.TOO_MANY_REQUESTS.value();
            }
        };
    }

    public static String getBlockString() {
        return JacksonUtils.toJsonString(
                ApiResponseWrapper.fail(getMessageWhenBlocked()).fromService());
    }

    public static ApiResponseWrapper<String> getBlockBody() {
        return ApiResponseWrapper.fail(getMessageWhenBlocked()).fromService();
    }

    public static String getMessageWhenBlocked() {
        return GenericMessageAccessor.getMessage(HttpStatus.TOO_MANY_REQUESTS.name());
    }
}